package com.xianggu.spring.transaction.proxy;

import com.xianggu.spring.transaction.annotation.Transactional;
import com.xianggu.spring.transaction.config.TransactionManager;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

public class TransactionAspect {

    private final TransactionManager transactionManager;
    private final Object target;

    public TransactionAspect(Object target) {
        this.transactionManager = new TransactionManager();
        this.target = target;
    }

    // 创建代理对象
    public Object createProxy(List<String> noProxyMethods) {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new TransactionInvocationHandler(noProxyMethods)
        );
    }

    // 事务处理的 InvocationHandler
    private class TransactionInvocationHandler implements InvocationHandler {
        private List<String> noProxyMethods;

        public TransactionInvocationHandler(List<String> noProxyMethods) {
            this.noProxyMethods = noProxyMethods;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 判断方法是否被 @Transactional 注解标记
//            if (true) {
            if (noProxyMethods.contains(method.getName())) {
                try {
                    transactionManager.begin(); // 开启事务
                    Object result = method.invoke(target, args); // 执行目标方法
                    transactionManager.commit(); // 提交事务
                    return result;
                } catch (Exception e) {
                    transactionManager.rollback(); // 回滚事务
                    throw e;
                }
            } else {
                return method.invoke(target, args); // 非事务方法直接执行
            }
        }
    }
}